// Copyright 2025 OPPO.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::FUSE_ROOT_ID;
use std::time::Duration;

// The cache inode property is the equivalent implementation of the libfuse node struct.
#[derive(Clone, Default, Debug)]
pub struct NodeAttr {
    // inode id, generated by curvine fuse.
    pub id: u64,

    // inode name.
    pub name: String,

    // The parent node id of the current inode.
    pub parent: u64,

    pub generation: u64,

    // Number of references, application layer
    pub ref_ctr: i32,

    // lookup times.Kernel layer.
    pub n_lookup: u64,

    // Turn on counting.
    pub open_count: i32,

    // inode update time.
    pub stat_updated: Duration,

    // Inode modification time in the file system.
    pub mtime: Duration,

    pub size: u64,

    pub is_hidden: bool,

    pub cache_valid: bool,
}

impl NodeAttr {
    pub fn new<T: AsRef<str>>(id: u64, name: Option<T>, parent: u64) -> Self {
        NodeAttr {
            id,
            parent,
            name: match name {
                None => "".to_string(),
                Some(v) => v.as_ref().to_string(),
            },
            ..Default::default()
        }
    }

    pub fn inc_lookup(&mut self) {
        if self.n_lookup == 0 {
            self.ref_ctr += 1;
        }
        self.n_lookup += 1;
    }

    pub fn is_root(&self) -> bool {
        self.id == FUSE_ROOT_ID
    }
}
